9.5 Список Задач + SQLite + Interface + DI
7 из 7 шагов пройдено

 Список Задач + SQLite + Interface + DI

➡️Ссылка на репозиторий с кодом этого урока

Подход 2: Через ORM

Он более читаемый, менее подвержен ошибкам в синтаксисе SQL и является предпочтительным для стандартных CRUD-операций (Create, Read, Update, Delete. 
Пакет sqflite сам формирует SQL-запрос из предоставленных данных.

ORM - Объектная обёртка над чистым SQL, нужна для удобства и надёжности при составлении и использовании запросов.

Файл lib/services/sqlite_orm_service.dart

import 'package:path/path.dart';  
import 'package:sqflite/sqflite.dart';  
import '../services/storage_interface.dart';  
import '../models/task.dart';  
  
class SqliteORMService implements IStorageService {  
  // Приватная переменная для хранения экземпляра БД  
  Database? _database;  
  
  static const _dbName = 'tasks_database.db'; // Название файла с бд  
  static const _tasksTableName = 'tasks'; // 1 таблица для списка задач  
  static const _settingsTableName = 'settings'; // 2 таблица для настроек  
  
  // Геттер для получения экземпляра БД.
  // Если он еще не создан, инициализирует его.
  Future<Database> get database async {  
    if (_database != null) {  
      return _database!;  
    }  
    _database = await _initDB();  
    return _database!;  
  }  
  
  /// Инициализация базы данных  
  Future<Database> _initDB() async {  
    // Получаем путь к каталогу для баз данных по умолчанию  
    // Для Android это data/data/<package_name>/databases
	final dbPath = await getDatabasesPath();  
    // Соединяем путь и имя файла БД  
    final path = join(dbPath, _dbName);  
  
    return await openDatabase(  
      path,  
      version: 1,  
      // onCreate выполняется 1 раз  
      onCreate: (db, version) async {  
        // Выполняем SQL-запрос для создания таблицы  
        await db.execute('''    
			CREATE TABLE $_tasksTableName(    
	            id INTEGER PRIMARY KEY AUTOINCREMENT,  
	            text TEXT NOT NULL,
				isDone INTEGER NOT NULL
			)
			''');  
        // Выполняем SQL-запрос для создания таблицы  
        await db.execute('''    
			CREATE TABLE $_settingsTableName(    
	            key TEXT PRIMARY KEY,  
	            value INTEGER
			)''');  
      },  
    );  
  }  
  
  /// Создание новой задачи  
  @override  
  Future<Task> createTask(String text) async {  
    final db = await database;  
  
    final newId = await db.insert(  
      _tasksTableName,  
      {'text': text, 'isDone': 0},  
    );  
  
    // Создаём и возвращаем объект Task с ID из базы данных.  
    return Task(id: newId, text: text, isDone: false);  
  }  
  
  /// Получение всех задач  
  @override  
  Future<List<Task>> getAllTasks() async {  
    final db = await database;  
    final List<Map<String, dynamic>> allTasks = await db.query(_tasksTableName);  
  
    // Преобразуем список Map в список объектов Task и возвращаем его  
    return List.generate(allTasks.length, (i) {  
      return Task(  
        id: allTasks[i]['id'],  
        text: allTasks[i]['text'],  
        isDone: allTasks[i]['isDone'] == 1,  
      );  
    });  
  }  
  
  /// Обновление задачи  
  @override  
  Future<void> updateTask(Task task) async {  
    final db = await database;  
  
    await db.update(  
      _tasksTableName,  
      {'text': task.text, 'isDone': task.isDone ? 1 : 0},  
      where: 'id = ?',  
      whereArgs: [task.id],  
    );  
  }  
  
  /// Удаление задачи  
  @override  
  Future<void> deleteTask(int id) async {  
    final db = await database;  
  
    await db.delete(_tasksTableName, where: 'id = ?', whereArgs: [id]);  
  }  
  
  /// Получение цветовой темы  
  @override  
  Future<bool> getThemeMode() async {  
    final db = await database;  
  
    final List<Map<String, dynamic>> settings = await db.query(  
      _settingsTableName,  
      columns: ['value'],  
      where: 'key = ?',  
      whereArgs: ['isDarkMode'],  
    );  
  
    if (settings.isNotEmpty) {  
	  return settings.first['value'] == 1;  
    }  
    return false;  
  }  
  
  /// Сохранение цветовой темы  
  @override  
  Future<void> saveThemeMode(bool isDarkMode) async {  
    final db = await database;  
  
    await db.insert(  
      _settingsTableName,  
      {'key': 'isDarkMode', 'value': isDarkMode ? 1 : 0},  
      conflictAlgorithm: ConflictAlgorithm.replace,  
    );  
  }  
}

Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий